package com.ruyiadmin.springboot.common.utils.core;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.ruyiadmin.springboot.common.beans.system.SM4Config;
import com.ruyiadmin.springboot.common.constants.business.SM4ModelType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;

/**
 * SM4加解密工具类
 *
 * @author RuYiAdmin
 * @since 2022-10-09
 */
@Component
@Slf4j
public class RuYiSM4Util {
    @Resource
    private SM4Config sm4Config;
    public static RuYiSM4Util sm4Util;

    @PostConstruct
    public void init() {
        sm4Util = this;
        sm4Util.sm4Config = this.sm4Config;
    }

    /**
     * 加密
     *
     * @param plainText 明文
     * @return 密文
     */
    public static String encrypt(String plainText) {
        String cipherText = StringUtils.EMPTY;

        log.info("当前模式：{}", sm4Util.sm4Config.getModel());

        switch (sm4Util.sm4Config.getModel()) {
            case SM4ModelType.CBC:
                SymmetricCrypto sm4cbc = new SymmetricCrypto("SM4/CBC/PKCS5Padding",
                        sm4Util.sm4Config.getSecretKey().getBytes());
                sm4cbc.setIv(new StringBuffer(sm4Util.sm4Config.getIV()).reverse().toString().getBytes(StandardCharsets.UTF_8));
                cipherText = sm4cbc.encryptHex(plainText);
                break;
            case SM4ModelType.ECB:
                SymmetricCrypto sm4ecb = new SymmetricCrypto("SM4/ECB/PKCS5Padding",
                        sm4Util.sm4Config.getSecretKey().getBytes());
                cipherText = sm4ecb.encryptHex(plainText);
                break;
        }

        return cipherText;
    }

    /**
     * 解密
     *
     * @param cipherText 密文
     * @return 明文
     */
    public static String decrypt(String cipherText) {
        String plainText = StringUtils.EMPTY;

        log.info("当前模式：{}", sm4Util.sm4Config.getModel());

        switch (sm4Util.sm4Config.getModel()) {
            case SM4ModelType.CBC:
                SymmetricCrypto sm4cbc = new SymmetricCrypto("SM4/CBC/PKCS5Padding",
                        sm4Util.sm4Config.getSecretKey().getBytes());
                sm4cbc.setIv(new StringBuffer(sm4Util.sm4Config.getIV()).reverse().toString().getBytes(StandardCharsets.UTF_8));
                plainText = sm4cbc.decryptStr(cipherText, CharsetUtil.CHARSET_UTF_8);
                break;
            case SM4ModelType.ECB:
                SymmetricCrypto sm4ecb = new SymmetricCrypto("SM4/ECB/PKCS5Padding",
                        sm4Util.sm4Config.getSecretKey().getBytes());
                plainText = sm4ecb.decryptStr(cipherText, CharsetUtil.CHARSET_UTF_8);
                break;
        }

        return plainText;
    }
}
